package com.jade.common.utils;

import com.jade.common.annotation.Declaration;
import com.jade.common.connector.DemoServiceTestConnector;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Component
public class Send2ServerUtilPlan2 {
	private static final Logger log = LoggerFactory
			.getLogger(Send2ServerUtilPlan2.class);
	@Autowired
	private RestTemplate restTemplate;

	// true 用http发送，其他用内部服务调用
	@Value("${demo.postSwitch}")
	public String postSwitch;

	@Value("${commom.isCloud}")
	private String isCloud;
	
	// true 用http发送，其他用内部服务调用
	@Value("${demo.urlPath}")
	public String urlPath;

	@Autowired
	private ApplicationContext applicationContext;

	public CommonResponse send2Server(
			DemoServiceTestConnector demoServiceTestConnector,
			Map<String, Object> map) {
		Declaration annotation = null;
		Class<? extends DemoServiceTestConnector> class1 = demoServiceTestConnector
				.getClass();
		boolean annotationPresent = class1
				.isAnnotationPresent(Declaration.class);
		if (annotationPresent) {
			annotation = class1.getAnnotation(Declaration.class);
		}

		if (annotation == null) {
			return CommonResponse.failResponse("接口声明错误，请联系对应接口人");
		}
		log.info("调用服务请求" + annotation.value());

		// 用集群服务。就用restTemplate，单点部署，就从AppletContext里面取bean
		if (StringUtils.equals("true", postSwitch)) {

			return sendHttp(annotation,map);

		} else {

			return localCall(annotation,map);
		}
	}

	/**
	 * HTTP调用，第一个参数是接口的声明注解，第二个是入参。
	 * @param annotation 
	 * 
	 * @param split
	 * @param parseObject
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private CommonResponse sendHttp(Declaration annotation, Map<String, Object> paramMap) {
		String serverName = annotation.value();
		serverName=serverName.substring(1,serverName.length());
		String[] split = serverName.split("\\/");
		if (!(split.length == 3)) {
			return CommonResponse.failResponse("方法名格式不合法");
		}
		paramMap.put("serverName",split[1]+"ServiceImpl");
		paramMap.put("methodName",split[2]);
		String gatwayUrl="";
		if(StringUtils.equals("true", isCloud)){
			 gatwayUrl="/"+split[0];
		}
		
		if (StringUtils.equals("post", annotation.method())) {
			
			Map<String, Object> body = restTemplate.postForEntity(
					urlPath+gatwayUrl +"/common/callService",
					paramMap, HashMap.class).getBody();
			
			log.info(body.toString());
			return CommonResponse.successResponse(body);
		} 
		return CommonResponse.failResponse();
	}
	
	
	
	/**
	 * HTTP调用，第一个参数是接口的声明注解，第二个是入参。
	 * @param annotation 
	 * 
	 * @param split
	 * @param parseObject
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private CommonResponse sendHttpOld(Declaration annotation, Map<String, Object> jsonParam) {
		Map <String,Object>map=new HashMap<String,Object>();
		map=(Map<String, Object>) jsonParam.get("paramMap");
		String serverName = annotation.value();
		serverName=serverName.substring(1,serverName.length());
		String[] split = serverName.split("\\/");
		if (!(split.length == 3)) {
			return CommonResponse.failResponse("方法名格式不合法");
		}
		map.put("serverName",split[1]+"ServiceImpl");
		map.put("methodName",split[2]);
		String gatwayUrl="";
		if(StringUtils.equals("true", isCloud)){
			 gatwayUrl="/"+split[0];
		}
		
		if (StringUtils.equals("post", annotation.method())) {
			
			Map<String, Object> body = restTemplate.postForEntity(
					urlPath + "/" + split[0] +gatwayUrl + "/" + split[2],
					jsonParam.get("paramMap"), HashMap.class).getBody();
			
			log.info(body.toString());
			return CommonResponse.successResponse(body);
		} else {
			Map<String, Object> paramMap = (Map<String, Object>) jsonParam
					.get("paramMap");
			Set<String> keySet = paramMap.keySet();
			String url = urlPath + gatwayUrl + "/" + split[1] + "/"
					+ split[2] + "?";
			for (String string : keySet) {
				url = url + "{" + string + "}" + "&";
			}
			url = url.substring(0, url.length() - 1);
			log.info("调用服务：" + url);
			String res = restTemplate.getForEntity(url,
					String.class, paramMap).getBody();
			log.info("调用服务成功返回值为：" + res);
			return CommonResponse.successResponse("成功", res);
		}
	}

	/**
	 * 本地调用，返回最后调用结果，第一个参数是接口的声明注解，第二个参数是参数对象
	 * @param annotation 
	 * 
	 * @param parseObject
	 * @param jsonParam
	 * @return
	 */
	private CommonResponse localCall(Declaration annotation, Map<String, Object> jsonParam) {
		String invoke = "";
		String[] split;
		Method[] methods;
		Object bean;
		String serverName = "";
		try {
			serverName =annotation.value();
			serverName=serverName.substring(1,serverName.length());
			log.info("调用本地方法:" + serverName);
			split = serverName.split("\\/");
			Class<?> Classes = applicationContext.getBean(split[1]+"ServiceImpl").getClass();
			methods = Classes.getMethods();
			bean = applicationContext.getBean(Classes);
		} catch (Exception e1) {
			e1.printStackTrace();
			log.error("调用本地方法失败：url=" + serverName);
			return CommonResponse.failResponse("方法名调用错误");
		}
		for (Method method : methods) {
			try {
				String name = method.getName();
				System.out.println("当前方法名为" + name + "目标方法名为" + split[2]);
				if (StringUtils.equals(split[2], name)) {
					invoke = (String) method.invoke(bean, jsonParam);
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("调用本地方法失败：url=" + serverName);
				return CommonResponse.failResponse(e.getMessage());
			}
		}
		return CommonResponse.successResponse(invoke);
	}

}
